Introduction: Control Ceiling Fan With an Echo Using a Raspberry Pi and Remote

Wanted to control my cheap Hampton Bay Ceiling fan with an Amazon Echo Dot. However, the fan is controlled with an RF remote control which isn't as easy to spoof as an IR remote. Found a few RF spoofing instructables but they looked like a lot of work and I do not have the electrical engineering skills required. I did have a spare remote so decided to trigger the buttons with the GPIO of a Raspberry Pi.

Acknowledgments:
Hacking the Amazon Echo by Fabricatel
Hack a Video Game Controller with an Arduino for Greater Accessibility (or Cheating) by DIY Hacks and How Tos
Amazon Echo and Home Automation
Raspberry PI B+/2 & 3 case by dktosoch

Step 1: List of Materials

Materials:

  • Raspberry Pi w/ SD card and power supply
  • Amazon Echo or Dot
  • Ceiling fan with RF remote control
  • NPN transistor (such as 2N3904)
  • 1k resistor (or similar)
  • Jumper wires
  • Electrical or Kapton tape (or shrink wrap)

Tools:

  • Soldering Iron and solder
  • Wire stripper
  • Drill press or hand drill or Dremel with a small bit
  • Screwdrivers (for opening the remote control)

Optional Items:

  • Raspberry Pi case
  • Small center punch and hammer

Step 2: Disassemble RF Remote Control

Take apart the remote. For me, it took 3 phillip screws and a little prying and the circuit board was free. The board has a green PCB side and a yellow side. On the green side, notice the circles with the copper traces. When the remote's buttons are pressed, metal disks push down on these circles connecting the traces. This connects the pull-up resister circuit to ground, driving the signal low that goes into the DIP. If we can tap into the signal side of these traces (not the side that goes to ground) and attach it to a GPIO pin on the Raspberry Pi then we can ground the signal by driving the GPIO pin low. The signal to the DIP will go low and will think the button was pressed.

The remote ran off a 9V battery, however, the Pi does not have a 9V output, only 3.3V and 5V. Wondered if the remote board would run off 5V instead so I looked up the DIP model number (HT-12E) which turned out to be an encoder IC specialized for remote control applications with RF or IR transmitters. More importantly, it accepts a range of voltages, 2.4V to 12V so 5V should work. Not entirely sure if the rest of the board would work off 5V so I hooked the remote board power lines to the Pi's 5V output and ground and the test shows the remote still worked. If you are worried about your board running off a different voltage, you could keep using batteries for power and triggering the buttons with the Pi GPIO will still work.

If you are going to power the remote board with the Pi's 5V then you have two options: connect the 5V and ground directly to the remote board which means it will be on whenever the Pi is on, OR use a NPN transistor and a GPIO pin to control the power and turn it on only when you want to activate a button. For this instructable, we will use a transistor.

Step 3: GPIO Pins and Circuit

The remote has 5 buttons so we need 5 GPIO pins plus 1 to control the optional transistor to power the remote board for a total of 6 GPIO pins. This instructable uses the Raspberry Pi 3 which has a 40 pin header. See the wiring diagram for the pins I picked towards the end of the header. Notice the NPN transistor circuit requires a resistor between the base and the GPIO pin.

On the off-chance that you still plan on using the physical buttons on the remote while also being hooked up to the Pi's GPIO, to be safe you should include a diode in-line. Otherwise, a high GPIO pin could short ground if the button is pressed. For more information about this, see the "Hacking a Video Gamer Controller" link from the intro. I do not plan on using the physical buttons so I did not include diodes in the diagram.

Step 4: Setup the Pi

Time to setup the Raspberry Pi. First, lets install Raspian which you can download directly from their website. Also on their website are instructions. You will need a HDMI monitor and USB mouse and keyboard hooked up to the Pi.

Once Raspian is installed, login as the "pi" user (default password is "raspberry") and open a command console and run the config script by entering "sudo raspi-config". You'll be presented with a menu. These are the settings you should change:

  • Change "pi" user password - for security, change the password to anything but the default
  • Under boot options:
    • (optional but recommended) Change to console mode - will use less energy and run cooler
    • Wait for network to boot - otherwise the fauxmo script will fail at startup because the wifi is still connecting
  • (optional) enable SSH - less secure but you can now access the Pi via a laptop with a SSH client instead of using a HDMI monitor and USB keyboard

When finished, exit the config script and reboot.

Step 5: Download and Configure Fauxmo

From the "Home Automation With Amazon Echo Voice Control" instructables, download the starter code (which includes fauxmo) and copy it to the Pi somewhere you will remember. For example, "/home/pi/" is a good place for it.

We are going to start with the "example-minimal.py" script and insert our code. First, make a copy of that script naming the new one something that makes sense, like "echo-fauxmo-bedroom.py". Next, make the following modifications to the new script.

At the top, add RPi.GPIO to the list of imported modules.

import RPi.GPIO as GPIO

In the main method, add the following code to the top. When the script is ran at startup, this will setup the GPIO pins as outputs and set them high, with the exception of the pin used for the NPN transistor...that is set low.

# Set GPIO pins high
GPIO.setmode(GPIO.BOARD)
GPIO.setup(40,GPIO.OUT,initial=0)
GPIO.setup(33,GPIO.OUT,initial=1)
GPIO.setup(35,GPIO.OUT,initial=1)
GPIO.setup(36,GPIO.OUT,initial=1)
GPIO.setup(37,GPIO.OUT,initial=1)
GPIO.setup(38,GPIO.OUT,initial=1)

Now we modify the device_handler class. Update the TRIGGERS list with the names you want for the buttons. You will use this name in the voice command. For example, if you choose the name "bedroom lights" your voice command will be "Alexa, turn on/off bedroom lights." For each name also pick a unique port number between 1024 and 49151.

TRIGGERS = {"bedroom lights": 3360,
	    "bedroom fan": 3361,
	    "bedroom fan low": 3362,
	    "bedroom fan medium": 3363,
	    "bedroom fan high": 3364}

Next we rewrite the act method. This is called whenever a voice command is received. The "name" argument will match the name of the voice commend received and we will use that to determine which GPIO pin to set. The "state" argument will be true or false depending on if the voice command was on or off. Using those two arguments, we'll determine which button needs pressed by setting the GPIO pin low for 1 second, then set it back to high. But first we turn on the power to the remote board by setting the GPIO pin connected to the transistor high then set it low when we are finished.

def act(self, client_address, state, name):
	print "State", state, "from client @", client_address, "name", name
	# Turn RF remote on
	GPIO.output(40,1)
	# Loop through triggers
	if name == "bedroom lights":
		GPIO.output(33,0)
		time.sleep(1)
		GPIO.output(33,1)
	elif name == "bedroom fan":
		if state:
			# using fan low as default for fan on
			GPIO.output(35,0)
			time.sleep(1)
			GPIO.output(35,1)
		else:
			GPIO.output(38,0)
			time.sleep(1)
			GPIO.output(38,1)
	elif name == "bedroom fan low":
		GPIO.output(35,0)
		time.sleep(1)
		GPIO.output(35,1)
	elif name == "bedroom fan medium":
		GPIO.output(36,0)
		time.sleep(1)
		GPIO.output(36,1)
	elif name == "bedroom fan high":
		GPIO.output(37,0)
		time.sleep(1)
		GPIO.output(37,1)
	GPIO.output(40,0)
	return True

The python script is finished but we need it to run at startup as root. We do this by adding it to the "/etc/rc.local" file. You will only be able to edit rc.local as root so don't forget to "sudo" when opening it. Enter the following line(s) to rc.local but change the path and/or filename to match your python script's location and filename.

# start our fauxmo python script
python /home/pi/echo-master/echo-fauxmo-bedroom.py

Reboot and the Pi is ready to go.

Step 6: Solder and Tape Wires

Time to solder the jumper wires to the remote board. The easiest way to do this is to drill small holes where the solder joints are on the traces. A drill press with a small bit is best but you should be able to do it with a hand drill or Dremel if you are careful. You may need to use a small center punch first to create a starter crater for the drill bit to catch on.

Next, we solder the transistor circuit, unless you decided not to use one and wire the Pi 5V output directly to the remote board, or use a battery. Remember the circuit diagram from step 3? Start by stripping the jumper wires and power wires coming off the remote board. Soldering the jumper wire for the Pi ground pin to the transistor emitter. Then solder the remote board's ground wire to the transistor collector. Next, solder the jumper wire for the GPIO pin to one end of the resistor. Solder the other end of the resistor to the transistor base.

Finish by taping up the wires so they are not exposed. I used electrical tape but you could also use kapton or shrink wrap.

Step 7: Package the Pi

The hardware is done but needs packaged. I 3D printed a case from Thingiverse but you could buy one instead. The remote board has two screw holes originally used to secure it to the plastic remote cover so I reused those holes to secure it to the top of the case with M3 screws. It doesn't look very pretty and I could have shortened the jumper wires some more but at this point, I just wanted to finish the project. Maybe in the future I'll go back and create a custom case to enclose the Pi and remote board along with all the wires.

Step 8: Discover New Devices and You Are Done!!!

Turn on the Pi and tell Echo to discover new devices. Verify via the Alexa app that all the TRIGGERS you put in the python script were found. Go ahead and try out the voice commands!

That's it. During the middle of the project, they announced the Raspberry Pi Zero with Wifi which should also work for this project since CPU speed isn't crucial and it still has plenty of GPIO pins.